/*
 * Copyright 2012 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package io.netty.channel;

import io.netty.bootstrap.Bootstrap;
import io.netty.util.concurrent.BlockingOperationException;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;

import java.util.concurrent.TimeUnit;


/**
 * 异步 {@link Channel} I/O 操作结果.
 * <p>
 * Netty 中, 所有 I/O 操作均是异步的.
 * 这意味着任意 I/O 调用将立刻返回, 而不保证在调用结束时, 请求的 I/O 操作是否已经完成.
 * 作为替代, 将返回一个 {@link ChannelFuture} 实例, 它将给到您该 I/O 操作相关的结果或状态信息.
 * <p>
 * {@link ChannelFuture} 要么是 <em>uncompleted</em>, 要么是 <em>completed</em>.
 * 当一个 I/O 操作开始, 一个新的 future 对象将被创建.
 * 新 future 初始为 uncompleted, 因为 I/O 操作还未结束, 不是 succeeded, failed, nor cancelled.
 * 如果 I/O 操作结束(successfully, with failure, by cancellation), 该 future 被标记为 completed, 同时带有更具体的信息, 如 failure 的原因.
 * 请注意: 即使是 failure and cancellation, 它们也属于 completed 状态.
 * <pre>
 *                                      +---------------------------+
 *                                      | Completed successfully    |
 *                                      +---------------------------+
 *                                 +---->      isDone() = true      |
 * +--------------------------+    |    |   isSuccess() = true      |
 * |        Uncompleted       |    |    +===========================+
 * +--------------------------+    |    | Completed with failure    |
 * |      isDone() = false    |    |    +---------------------------+
 * |   isSuccess() = false    |----+---->      isDone() = true      |
 * | isCancelled() = false    |    |    |       cause() = non-null  |
 * |       cause() = null     |    |    +===========================+
 * +--------------------------+    |    | Completed by cancellation |
 *                                 |    +---------------------------+
 *                                 +---->      isDone() = true      |
 *                                      | isCancelled() = true      |
 *                                      +---------------------------+
 * </pre>
 * <p>
 * 提供了多种方法, 便于您检查 I/O 操作是否已经 completed, 等待完成, 获取 I/O 操作的结果.
 * 同样允许您添加 {@link ChannelFutureListener}s, 当 I/O 操作完成时, 您可以得到通知.
 *
 * <h3>Prefer {@link #addListener(GenericFutureListener)} to {@link #await()}</h3>
 * <p>
 * 在任何可能的情况下, 相较于 {@link #await()}, 建议使用 {@link #addListener(GenericFutureListener)},
 * 以在 I/O 操作完成时得到通知, 执行后续任务.
 * <p>
 * {@link #addListener(GenericFutureListener)} 是非阻塞的.
 * 它只是简单地将指定 {@link ChannelFutureListener} 添加到 {@link ChannelFuture}, 然后当此 future 相关联的 I/O 操作完成时,
 * I/O 线程将通知监听者.
 * {@link ChannelFutureListener} 完全不阻塞, 因此可产生最佳的性能和最高的资源利用率, 但是如果您不习惯事件驱动(event-driven)编程,
 * 那么实现顺序逻辑可能会比较棘手.
 * <p>
 * 于此相反地, {@link #await()} 是一个阻塞操作.
 * 一旦被调用, 调用者的线程将被阻塞直至操作完成.
 * 使用 {@link #await()} 来实现顺序逻辑更加简单, 但是在 I/O 操作完成前, 调用者的线程将不必要的等待, 同时还会有相对高的线程间通知.
 * 此外, 在特定情况下还可能出现死锁, 这将在下面进行描述.
 *
 * <h3>不要在 {@link ChannelHandler} 内调用 {@link #await()}</h3>
 * <p>
 * {@link ChannelHandler} 中的 event handler 方法通常被一个 I/O 线程调用.
 * 如果 event handler 被 I/O 线程调用, 同时它又调用了 {@link #await()}, 那么 {@link #await()} 等待的 I/O 操作可能永远不会完成,
 * 因为 {@link #await()} 可能阻塞它等待的 I/O 操作, 这形成了死锁.
 * <pre>
 * // BAD - NEVER DO THIS
 * {@code @Override}
 * public void channelRead({@link ChannelHandlerContext} ctx, Object msg) {
 *     {@link ChannelFuture} future = ctx.channel().close();
 *     future.awaitUninterruptibly();
 *     // Perform post-closure operation
 *     // ...
 * }
 *
 * // GOOD
 * {@code @Override}
 * public void channelRead({@link ChannelHandlerContext} ctx, Object msg) {
 *     {@link ChannelFuture} future = ctx.channel().close();
 *     future.addListener(new {@link ChannelFutureListener}() {
 *         public void operationComplete({@link ChannelFuture} future) {
 *             // Perform post-closure operation
 *             // ...
 *         }
 *     });
 * }
 * </pre>
 * <p>
 * 尽管存在上述缺点, 但是在某些情况下, 调用 {@link #await()} 更为方便.
 * 在此场景下, 请确保不要在 I/O 线程调用 {@link #await()}. 否则, 将抛出 {@link BlockingOperationException} 以防死锁发生.
 *
 * <h3>不要混淆 I/O timeout and await timeout</h3>
 * <p>
 * 在如下方法中指定的超时时间:
 *  - {@link #await(long)}
 *  - {@link #await(long, TimeUnit)}
 *  - {@link #awaitUninterruptibly(long)}
 *  - {@link #awaitUninterruptibly(long, TimeUnit)}
 * 同 I/O 超时毫不相干.
 * 如果一个 I/O 操作超时, 该 future 将被标记为 'completed with failure'(具体请查看上面图示).
 * 例如, 连接超时时间应该通过特定于 transport 的选项进行配置:
 * <pre>
 * // BAD - NEVER DO THIS
 * {@link Bootstrap} b = ...;
 * {@link ChannelFuture} f = b.connect(...);
 * f.awaitUninterruptibly(10, TimeUnit.SECONDS);
 * if (f.isCancelled()) {
 *     // Connection attempt cancelled by user
 * } else if (!f.isSuccess()) {
 *     // You might get a NullPointerException here because the future
 *     // might not be completed yet.
 *     f.cause().printStackTrace();
 * } else {
 *     // Connection established successfully
 * }
 *
 * // GOOD
 * {@link Bootstrap} b = ...;
 * // Configure the connect timeout option.
 * <b>b.option({@link ChannelOption}.CONNECT_TIMEOUT_MILLIS, 10000);</b>
 * {@link ChannelFuture} f = b.connect(...);
 * f.awaitUninterruptibly();
 *
 * // Now we are sure the future is completed.
 * assert f.isDone();
 *
 * if (f.isCancelled()) {
 *     // Connection attempt cancelled by user
 * } else if (!f.isSuccess()) {
 *     f.cause().printStackTrace();
 * } else {
 *     // Connection established successfully
 * }
 * </pre>
 */
public interface ChannelFuture extends Future<Void> {

    /**
     * 返回该 future 相关的 I/O 操作发生在的 channel
     */
    Channel channel();

    @Override
    ChannelFuture addListener(GenericFutureListener<? extends Future<? super Void>> listener);

    @Override
    ChannelFuture addListeners(GenericFutureListener<? extends Future<? super Void>>... listeners);

    @Override
    ChannelFuture removeListener(GenericFutureListener<? extends Future<? super Void>> listener);

    @Override
    ChannelFuture removeListeners(GenericFutureListener<? extends Future<? super Void>>... listeners);

    @Override
    ChannelFuture sync() throws InterruptedException;

    @Override
    ChannelFuture syncUninterruptibly();

    @Override
    ChannelFuture await() throws InterruptedException;

    @Override
    ChannelFuture awaitUninterruptibly();

    /**
     * 如果该 {@link ChannelFuture} 是 void future, 并且不允许调用以下方法时, 返回 {@code true}:
     * <ul>
     *     <li>{@link #addListener(GenericFutureListener)}</li>
     *     <li>{@link #addListeners(GenericFutureListener[])}</li>
     *     <li>{@link #await()}</li>
     *     <li>{@link #await(long, TimeUnit)} ()}</li>
     *     <li>{@link #await(long)} ()}</li>
     *     <li>{@link #awaitUninterruptibly()}</li>
     *     <li>{@link #sync()}</li>
     *     <li>{@link #syncUninterruptibly()}</li>
     * </ul>
     */
    boolean isVoid();
}
